package com.navinfo.platform.dataanalysis.service.impl;

import com.navinfo.location.mileage.bean.MileageAndFuel;
import com.navinfo.location.mileage.bean.Point;
import com.navinfo.location.mileage.calculation.Calculation;
import com.navinfo.platform.common.dto.DataInfo;
import com.navinfo.platform.common.service.ICommonService;
import com.navinfo.platform.common.service.IDataHandleService;
import com.navinfo.platform.common.utils.TidPartitioner;
import com.navinfo.platform.dataanalysis.dto.CachePoint;
import com.navinfo.platform.dataanalysis.dto.LocationDataPoint;
import com.navinfo.platform.dataanalysis.dto.UsefulSpeed;
import com.navinfo.platform.dataanalysis.dto.VehicleBaseStatisticsDay;
import com.navinfo.platform.dataanalysis.range.*;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.broadcast.Broadcast;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SaveMode;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.storage.StorageLevel;
import scala.Tuple2;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public enum GasDataHandleService implements IDataHandleService {
    INSTANCE;

    @Override
    public void handle(List<Object> obj, Map<String, String> configMap, SparkSession spark) {
        Dataset<Row> locationDataset = (Dataset<Row>) obj.get(0);
        Dataset<Row> trip375 = (Dataset<Row>) obj.get(1);
        Dataset<Row> trip500 = (Dataset<Row>) obj.get(2);

        Set<Long> set375 = trip375.collectAsList().stream().<Long>map(row -> Long.valueOf(row.getAs("value"))).collect(Collectors.toSet());
        Set<Long> set500 = trip500.collectAsList().stream().<Long>map(row -> Long.valueOf(row.getAs("value"))).collect(Collectors.toSet());
        final Broadcast<Set<Long>> broadcast375 = new JavaSparkContext(spark.sparkContext()).broadcast(set375);
        final Broadcast<Set<Long>> broadcast500 = new JavaSparkContext(spark.sparkContext()).broadcast(set500);

        JavaPairRDD<Long, List<DataInfo>> locationRDD = convert(locationDataset, configMap);
        locationRDD.persist(StorageLevel.MEMORY_AND_DISK());

        JavaPairRDD<Long, List<DataInfo>> local375 = locationRDD.filter(v1 -> broadcast375.value().contains(v1._1));
        JavaPairRDD<Long, List<DataInfo>> local500 = locationRDD.filter(v1 -> broadcast500.value().contains(v1._1));

        String day = configMap.get(ICommonService.DAY_VALUE);
        String path375 = String.format(configMap.get("hdfs.gas.375.path"), day);
        String path500 = String.format(configMap.get("hdfs.gas.500.path"), day);
//        String pathBase = String.format(configMap.get("hdfs.statistics.day.path"), day);

        //375车型落盘
        handle(local375, configMap, spark, path375);

        //500车型落盘
        handle(local500, configMap, spark, path500);

        //基础统计落盘
        //handle(convert(baseDataset, configMap), configMap, spark, pathBase);
    }

    private JavaPairRDD<Long, List<DataInfo>> convert(Dataset<Row> locationDataset, Map<String, String> configMap){
        String num = configMap.get(ICommonService.PARTITION_NUM_VALUE);
        int partitionNum = Optional.ofNullable(num).map(u -> Integer.parseInt(u)).orElse(1024);

        return locationDataset.toJavaRDD().mapPartitionsToPair(
                (PairFlatMapFunction<Iterator<Row>, Long, DataInfo>) iterator -> {
                    Iterable<Row> iterable = () -> iterator;
                    return StreamSupport.stream(iterable.spliterator(), false)
                            .map(s -> {
                                DataInfo locationDataPoint = LocationDataPoint.parseObj(s);
                                return new Tuple2<>(locationDataPoint.getTid(), locationDataPoint);
                            }).iterator();
                }).partitionBy(new TidPartitioner(partitionNum)).combineByKey(
                (Function<DataInfo, List<DataInfo>>) point -> Stream.of(point)
                        .collect(Collectors.toList()),
                (Function2<List<DataInfo>, DataInfo, List<DataInfo>>) (points, p) ->
                {
                    points.add(p);
                    return points;
                }
                ,
                (Function2<List<DataInfo>, List<DataInfo>, List<DataInfo>>) (p1, p2) ->
                {
                    p1.addAll(p2);
                    return p1;
                }).mapPartitionsToPair(
                (PairFlatMapFunction<Iterator<Tuple2<Long, List<DataInfo>>>, Long, List<DataInfo>>) tuple2Iterator -> {
                    Iterable<Tuple2<Long, List<DataInfo>>> iterator = () -> tuple2Iterator;
                    return StreamSupport.stream(iterator.spliterator(), false)
                            .map(t -> {
                                t._2.sort(Comparator.comparingLong(value -> value.getGpsDate()));
                                return new Tuple2<>(t._1, t._2);
                            }).iterator();
                });
    }

    /**
     * 统计各项指标
     * @param javaPairRDD
     * @param configMap
     * @param spark
     * @return
     */
    public Dataset<Row> handle(JavaPairRDD<Long, List<DataInfo>> javaPairRDD,  Map<String, String> configMap, SparkSession spark, String path) {
        JavaSparkContext jsc = new JavaSparkContext(spark.sparkContext());
        String day = configMap.get(ICommonService.DAY_VALUE);
        int vehicleStartRotation = Integer.parseInt(configMap.get("vehicle.start.rotation"));
        int workHoursThreshold = Integer.parseInt(configMap.get("work.hours.threshold"));
        int workSpeedThreshold = Integer.parseInt(configMap.get("work.speed.threshold"));
        double usefulPercent = Double.parseDouble(configMap.get("useful.percent.threshold"));

        JavaRDD<VehicleBaseStatisticsDay> vehicleBaseStatisticsDay = javaPairRDD.mapPartitions(
                (FlatMapFunction<Iterator<Tuple2<Long, List<DataInfo>>>, VehicleBaseStatisticsDay>) iterator -> {
                    Iterable<Tuple2<Long, List<DataInfo>>> iterable = () -> iterator;
                    return StreamSupport.stream(iterable.spliterator(), false)
                            .map(s -> getVehicleBaseStatisticsDay(day, workHoursThreshold, workSpeedThreshold, vehicleStartRotation, usefulPercent, s))
                            .iterator();
                }
        );

        Dataset<Row> dataFrame = spark.createDataFrame(vehicleBaseStatisticsDay, VehicleBaseStatisticsDay.class);
        dataFrame.select(VehicleBaseStatisticsDay.columns()).repartition(1).write().mode(SaveMode.Overwrite).parquet(path);
        return dataFrame;
    }

    /**
     * @param day
     * @param workHoursThreshold
     * @param workSpeedThreshold
     * @param usefulPercent
     * @param t
     * @return
     */
    private VehicleBaseStatisticsDay getVehicleBaseStatisticsDay(String day,
                                                                 int workHoursThreshold,
                                                                 int workSpeedThreshold,
                                                                 int vehicleStartRotation,
                                                                 double usefulPercent,
                                                                 Tuple2<Long, List<DataInfo>> t) {
        VehicleBaseStatisticsDay vehicleBaseStatisticsDay = new VehicleBaseStatisticsDay();
        vehicleBaseStatisticsDay.setTid(t._1);
        vehicleBaseStatisticsDay.setUid(t._1);
        vehicleBaseStatisticsDay.setDay(day);
        List<DataInfo> locationDataPoints = t._2;
        setDefaultVal(vehicleBaseStatisticsDay);
        CachePoint cachePoint = new CachePoint();
        List<Point> points = new ArrayList<>(2500);
        UsefulSpeed usefulSpeed = new UsefulSpeed();
        for (DataInfo dataInfo : locationDataPoints) {
            LocationDataPoint locationDataPoint = (LocationDataPoint) dataInfo;
            int duration = calDuration(workHoursThreshold, cachePoint, locationDataPoint);
            calWorkDuration(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
                    vehicleStartRotation);
//            calSpeedRange(vehicleBaseStatisticsDay, locationDataPoint, duration, usefulSpeed);
//            calWaterTempRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
//                    vehicleStartRotation);
            calGasOpenPercentRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
                    vehicleStartRotation);
//            calTorqueRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
//                    vehicleStartRotation);
//            calRotationRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
//                    vehicleStartRotation);
//            calIntakeAirTempRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
//                    vehicleStartRotation);
//            calIntakeAirPressureRange(vehicleBaseStatisticsDay, locationDataPoint, duration, workSpeedThreshold,
//                    vehicleStartRotation);
            points.add(locationDataPoint.toPoint());
        }
//        calMileageAndFuel(vehicleBaseStatisticsDay, points);
//        correctSpeedRange(vehicleBaseStatisticsDay);
//        correctWaterTempRange(vehicleBaseStatisticsDay);
        correctGasOpenPercentRange(vehicleBaseStatisticsDay);
//        correctTorqueRange(vehicleBaseStatisticsDay);
//        correctRotationRange(vehicleBaseStatisticsDay);
//        correctIntakeAirTempRange(vehicleBaseStatisticsDay);
//        correctIntakeAirPressureRange(vehicleBaseStatisticsDay);
//        calAvgSpeed(vehicleBaseStatisticsDay, usefulPercent, usefulSpeed);
        return vehicleBaseStatisticsDay;
    }

    public void setDefaultVal(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        vehicleBaseStatisticsDay.setWorkDuration(0);
        vehicleBaseStatisticsDay.setGasOpenPercentSum(0L);
        vehicleBaseStatisticsDay.setGasOpenPercentCount(0);
        vehicleBaseStatisticsDay.setAvgGasOpenPercent(0);
        vehicleBaseStatisticsDay.setIatSum(0L);
        vehicleBaseStatisticsDay.setIatCount(0);
        vehicleBaseStatisticsDay.setAvgIat(0);
        vehicleBaseStatisticsDay.setIdleWaterTempSum(0L);
        vehicleBaseStatisticsDay.setIdleWaterTempCount(0);
        vehicleBaseStatisticsDay.setAvgIdleWaterTemp(0);
        vehicleBaseStatisticsDay.setWorkWaterTempSum(0L);
        vehicleBaseStatisticsDay.setWorkWaterTempCount(0);
        vehicleBaseStatisticsDay.setAvgWorkWaterTemp(0);
        vehicleBaseStatisticsDay.setIpSum(0L);
        vehicleBaseStatisticsDay.setIpCount(0);
        vehicleBaseStatisticsDay.setAvgIp(0);
        vehicleBaseStatisticsDay.setNoIdleRpmSum(0L);
        vehicleBaseStatisticsDay.setNoIdleRpmCount(0);
        vehicleBaseStatisticsDay.setNoIdleAvgRpm(0);
        vehicleBaseStatisticsDay.setRpmSum(0L);
        vehicleBaseStatisticsDay.setRpmCount(0);
        vehicleBaseStatisticsDay.setAvgRpm(0);
        vehicleBaseStatisticsDay.setTorqueSum(0L);
        vehicleBaseStatisticsDay.setTorqueCount(0);
        vehicleBaseStatisticsDay.setAvgTorque(0);
    }

    /**
     * 计算两点之间时长
     *
     * @param workHoursThreshold
     * @param cachePoint
     * @param locationDataPoint
     */
    public int calDuration(int workHoursThreshold,
                           CachePoint cachePoint,
                           LocationDataPoint locationDataPoint) {
        int duration = 0;
        if (cachePoint.getGpsDate() != 0L) {
            //差值转换成秒
            long diffTime = locationDataPoint.getGpsDate() - cachePoint.getGpsDate();
            cachePoint.setGpsDate(locationDataPoint.getGpsDate());
            if (diffTime <= workHoursThreshold) {
                duration = (int) diffTime;
            }
        } else {
            cachePoint.setGpsDate(locationDataPoint.getGpsDate());
        }
        return duration;
    }

    /**
     * 计算工作时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     * @param workHoursSpeedThreshold
     */
    public void calWorkDuration(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                LocationDataPoint locationDataPoint,
                                int duration,
                                int workHoursSpeedThreshold,
                                int vehicleStartRotation) {
        int speed = locationDataPoint.getSpeed();
        int rotation = locationDataPoint.getRotation();
        if (isWork(workHoursSpeedThreshold, vehicleStartRotation, speed, rotation)) {
            vehicleBaseStatisticsDay.setWorkDuration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getWorkDuration()).orElse(0) + duration);
        }
    }

    /**
     * 判断工作
     *
     * @param workHoursSpeedThreshold
     * @param vehicleStartRotation
     * @param speed
     * @param rotation
     * @return
     */
    public boolean isWork(int workHoursSpeedThreshold, int vehicleStartRotation, int speed, int rotation) {
        return speed > workHoursSpeedThreshold && rotation > vehicleStartRotation;
    }

    /**
     * 判断怠速
     *
     * @param workHoursSpeedThreshold
     * @param vehicleStartRotation
     * @param speed
     * @param rotation
     * @return
     */
    public boolean isIdle(int workHoursSpeedThreshold, int vehicleStartRotation, int speed, int rotation) {
        return speed <= workHoursSpeedThreshold && rotation > vehicleStartRotation;
    }


    /**
     * 计算速度区间时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     * @param usefulSpeed
     */
    public void calSpeedRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                              LocationDataPoint locationDataPoint,
                              int duration,
                              UsefulSpeed usefulSpeed) {
        int speed = locationDataPoint.getSpeed();
        if (!SpeedRange.SPEED_VALID.getRange().contains(speed)) {
            return;
        }
        if (SpeedRange.SPEED_RANGE_10.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed10Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed10Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed10MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed10MinUsefulSpeed()) {
                usefulSpeed.setSpeed10MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed10MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed10MaxUsefulSpeed()) {
                usefulSpeed.setSpeed10MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_20.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed20Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed20Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed20MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed20MinUsefulSpeed()) {
                usefulSpeed.setSpeed20MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed20MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed20MaxUsefulSpeed()) {
                usefulSpeed.setSpeed20MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_30.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed30Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed30Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed30MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed30MinUsefulSpeed()) {
                usefulSpeed.setSpeed30MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed30MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed30MaxUsefulSpeed()) {
                usefulSpeed.setSpeed30MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_40.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed40Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed40Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed40MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed40MinUsefulSpeed()) {
                usefulSpeed.setSpeed40MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed40MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed40MaxUsefulSpeed()) {
                usefulSpeed.setSpeed40MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_50.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed50Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed50Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed50MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed50MinUsefulSpeed()) {
                usefulSpeed.setSpeed50MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed50MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed50MaxUsefulSpeed()) {
                usefulSpeed.setSpeed50MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_60.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed60Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed60Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed60MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed60MinUsefulSpeed()) {
                usefulSpeed.setSpeed60MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed60MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed60MaxUsefulSpeed()) {
                usefulSpeed.setSpeed60MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_70.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed70Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed70Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed70MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed70MinUsefulSpeed()) {
                usefulSpeed.setSpeed70MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed70MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed70MaxUsefulSpeed()) {
                usefulSpeed.setSpeed70MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_80.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed80Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed80Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed80MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed80MinUsefulSpeed()) {
                usefulSpeed.setSpeed80MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed80MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed80MaxUsefulSpeed()) {
                usefulSpeed.setSpeed80MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_90.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed90Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed90Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed90MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed90MinUsefulSpeed()) {
                usefulSpeed.setSpeed90MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed90MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed90MaxUsefulSpeed()) {
                usefulSpeed.setSpeed90MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_100.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed100Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed100Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed100MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed100MinUsefulSpeed()) {
                usefulSpeed.setSpeed100MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed100MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed100MaxUsefulSpeed()) {
                usefulSpeed.setSpeed100MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_110.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed110Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed110Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed110MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed110MinUsefulSpeed()) {
                usefulSpeed.setSpeed110MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed110MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed110MaxUsefulSpeed()) {
                usefulSpeed.setSpeed110MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_120.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeed120Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed120Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeed120MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeed120MinUsefulSpeed()) {
                usefulSpeed.setSpeed120MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeed120MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeed120MaxUsefulSpeed()) {
                usefulSpeed.setSpeed120MaxUsefulSpeed(speed);
            }
        } else if (SpeedRange.SPEED_RANGE_OVER_120.getRange().contains(speed)) {
            vehicleBaseStatisticsDay.setSpeedOver120Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getSpeedOver120Duration()).orElse(0) + duration);
            if (usefulSpeed.getSpeedOver120MinUsefulSpeed() == null
                    || speed < usefulSpeed.getSpeedOver120MinUsefulSpeed()) {
                usefulSpeed.setSpeedOver120MinUsefulSpeed(speed);
            }
            if (usefulSpeed.getSpeedOver120MaxUsefulSpeed() == null
                    || speed > usefulSpeed.getSpeedOver120MaxUsefulSpeed()) {
                usefulSpeed.setSpeedOver120MaxUsefulSpeed(speed);
            }
        }
        if (vehicleBaseStatisticsDay.getMaxSpeed() == null) {
            vehicleBaseStatisticsDay.setMaxSpeed(speed);
        } else {
            int maxSpeed = vehicleBaseStatisticsDay.getMaxSpeed() < speed ?
                    speed : vehicleBaseStatisticsDay.getMaxSpeed();
            vehicleBaseStatisticsDay.setMaxSpeed(maxSpeed);
        }
    }

    /**
     * 计算水温时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     */
    public void calWaterTempRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                  LocationDataPoint locationDataPoint,
                                  int duration,
                                  int workSpeedThreshold, int vehicleStartRotation) {
        int speed = locationDataPoint.getSpeed();
        int rotation = locationDataPoint.getRotation();
        int waterTem = locationDataPoint.getCoolingWaterTem();
        if (!WaterTempRange.WATER_TEMP_RANGE_VALID.getRange().contains(waterTem)) {
            return;
        }
        boolean work = isWork(workSpeedThreshold, vehicleStartRotation, speed, rotation);
        boolean idle = isIdle(workSpeedThreshold, vehicleStartRotation, speed, rotation);
        if (WaterTempRange.WATER_TEMP_RANGE_50.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp50Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp50Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp50Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp50Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_70.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp70Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp70Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp70Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp70Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_80.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp80Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp80Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp80Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp80Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_85.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp85Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp85Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp85Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp85Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_90.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp90Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp90Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp90Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp90Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_95.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp95Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp95Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp95Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp95Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_100.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp100Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp100Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp100Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp100Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_105.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp105Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp105Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp105Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp105Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_110.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp110Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp110Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp110Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp110Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_115.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp115Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp115Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp115Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp115Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_120.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp120Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp120Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp120Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp120Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_125.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp125Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp125Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp125Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp125Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_130.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp130Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp130Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp130Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp130Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_135.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp135Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp135Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp135Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp135Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_140.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp140Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp140Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp140Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp140Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_145.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp145Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp145Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp145Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp145Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_150.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTemp150Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp150Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTemp150Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp150Duration()).orElse(0)
                                + duration);
            }
        } else if (WaterTempRange.WATER_TEMP_RANGE_OVER_150.getRange().contains(waterTem)) {
            if (work) {
                vehicleBaseStatisticsDay.setWorkWaterTempOver150Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTempOver150Duration()).orElse(0)
                                + duration);
            } else if (idle) {
                vehicleBaseStatisticsDay.setIdleWaterTempOver150Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTempOver150Duration()).orElse(0)
                                + duration);
            }
        }

        if (work) {
            if (vehicleBaseStatisticsDay.getMaxWorkWaterTemp() == null
                    || waterTem > vehicleBaseStatisticsDay.getMaxWorkWaterTemp()) {
                vehicleBaseStatisticsDay.setMaxWorkWaterTemp(waterTem);
            }
            if (vehicleBaseStatisticsDay.getMinWorkWaterTemp() == null
                    || waterTem < vehicleBaseStatisticsDay.getMinWorkWaterTemp()) {
                vehicleBaseStatisticsDay.setMinWorkWaterTemp(waterTem);
            }
            vehicleBaseStatisticsDay.setWorkWaterTempSum(vehicleBaseStatisticsDay.getWorkWaterTempSum() + waterTem);
            vehicleBaseStatisticsDay.setWorkWaterTempCount(vehicleBaseStatisticsDay.getWorkWaterTempCount() + 1);
            int avgWorkWaterTemp = BigDecimal.valueOf(vehicleBaseStatisticsDay.getWorkWaterTempSum()).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getWorkWaterTempCount()), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setAvgWorkWaterTemp(avgWorkWaterTemp);
        } else if (idle) {
            if (vehicleBaseStatisticsDay.getMaxIdleWaterTemp() == null ||
                    waterTem > vehicleBaseStatisticsDay.getMaxIdleWaterTemp()) {
                vehicleBaseStatisticsDay.setMaxIdleWaterTemp(waterTem);
            }
            if (vehicleBaseStatisticsDay.getMinIdleWaterTemp() == null
                    || waterTem < vehicleBaseStatisticsDay.getMinIdleWaterTemp()) {
                vehicleBaseStatisticsDay.setMinIdleWaterTemp(waterTem);
            }
            vehicleBaseStatisticsDay.setIdleWaterTempSum(vehicleBaseStatisticsDay.getIdleWaterTempSum() + waterTem);
            vehicleBaseStatisticsDay.setIdleWaterTempCount(vehicleBaseStatisticsDay.getIdleWaterTempCount() + 1);
            int avgIdleWaterTemp = BigDecimal.valueOf(vehicleBaseStatisticsDay.getIdleWaterTempSum()).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getIdleWaterTempCount()), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setAvgIdleWaterTemp(avgIdleWaterTemp);
        }
    }

    /**
     * 计算油门开度时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     * @param workSpeedThreshold
     */
    public void calGasOpenPercentRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                       LocationDataPoint locationDataPoint,
                                       int duration,
                                       int workSpeedThreshold, int vehicleStartRotation) {
        int speed = locationDataPoint.getSpeed();
        int rotation = locationDataPoint.getRotation();
        int accPedalPos = locationDataPoint.getAccPedalPos();
        if (!GasOpenPercentRange.GAS_OPEN_PERCENT_VALID.getRange().contains(accPedalPos)) {
            return;
        }

        boolean work = isWork(workSpeedThreshold, vehicleStartRotation, speed, rotation);
        if (work) {
            if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_0.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent0Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent0Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_10.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent10Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent10Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_20.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent20Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent20Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_30.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent30Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent30Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_40.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent40Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent40Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_50.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent50Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent50Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_60.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent60Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent60Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_70.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent70Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent70Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_80.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent80Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent80Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_90.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent90Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent90Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_99.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent99Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent99Duration()).orElse(0)
                                + duration);
            } else if (GasOpenPercentRange.GAS_OPEN_PERCENT_RANGE_100.getRange().contains(accPedalPos)) {
                vehicleBaseStatisticsDay.setGasOpenPercent100Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent100Duration()).orElse(0)
                                + duration);
            }
            vehicleBaseStatisticsDay.setGasOpenPercentSum(
                    vehicleBaseStatisticsDay.getGasOpenPercentSum() + accPedalPos);
            vehicleBaseStatisticsDay.setGasOpenPercentCount(vehicleBaseStatisticsDay.getGasOpenPercentCount() + 1);
            int avgGasOpenPercent = BigDecimal.valueOf(vehicleBaseStatisticsDay.getGasOpenPercentSum()).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getGasOpenPercentCount()), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setAvgGasOpenPercent(avgGasOpenPercent);
        }
    }

    /**
     * 计算扭矩时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     * @param workSpeedThreshold
     */
    public void calTorqueRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                               LocationDataPoint locationDataPoint,
                               int duration,
                               int workSpeedThreshold,
                               int vehicleStartRotation) {
        int speed = locationDataPoint.getSpeed();
        int rotation = locationDataPoint.getRotation();
        int actualEnginePercentTor = locationDataPoint.getActualEnginePercentTor();
        if (!TorqueRange.TORQUE_RANGE_VALID.getRange().contains(actualEnginePercentTor)) {
            return;
        }
        boolean work = isWork(workSpeedThreshold, vehicleStartRotation, speed, rotation);
        if (work) {
            if (TorqueRange.TORQUE_RANGE_0.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque0Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque0Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_10.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque10Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque10Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_20.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque20Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque20Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_30.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque30Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque30Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_40.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque40Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque40Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_50.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque50Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque50Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_60.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque60Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque60Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_70.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque70Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque70Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_80.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque80Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque80Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_90.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque90Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque90Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_99.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque99Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque99Duration()).orElse(0)
                                + duration);
            } else if (TorqueRange.TORQUE_RANGE_100.getRange().contains(actualEnginePercentTor)) {
                vehicleBaseStatisticsDay.setTorque100Duration(
                        Optional.ofNullable(vehicleBaseStatisticsDay.getTorque100Duration()).orElse(0)
                                + duration);
            }

            if (vehicleBaseStatisticsDay.getMaxTorque() == null
                    || actualEnginePercentTor > vehicleBaseStatisticsDay.getMaxTorque()) {
                vehicleBaseStatisticsDay.setMaxTorque(actualEnginePercentTor);
            }
            if (vehicleBaseStatisticsDay.getMinTorque() == null
                    || actualEnginePercentTor < vehicleBaseStatisticsDay.getMinTorque()) {
                vehicleBaseStatisticsDay.setMinTorque(actualEnginePercentTor);
            }

            vehicleBaseStatisticsDay.setTorqueSum(vehicleBaseStatisticsDay.getTorqueSum() + actualEnginePercentTor);
            vehicleBaseStatisticsDay.setTorqueCount(vehicleBaseStatisticsDay.getTorqueCount() + 1);
            int avgTorque = BigDecimal.valueOf(vehicleBaseStatisticsDay.getTorqueSum()).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getTorqueCount()), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setAvgTorque(avgTorque);
        }
    }

    /**
     * 计算转速区间时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     * @param workSpeedThreshold
     * @param vehicleStartRotation
     */
    public void calRotationRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                 LocationDataPoint locationDataPoint,
                                 int duration,
                                 int workSpeedThreshold,
                                 int vehicleStartRotation) {
        int speed = locationDataPoint.getSpeed();
        int rotation = locationDataPoint.getRotation();
        if (!RotationRange.RPM_RANGE_OVER_VALID.getRange().contains(rotation)) {
            return;
        }
        if (RotationRange.RPM_RANGE_650.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm650Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm650Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_800.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm800Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm800Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_1100.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm1100Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1100Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_1400.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm1400Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1400Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_1700.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm1700Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1700Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_2000.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm2000Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2000Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_2300.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm2300Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2300Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_2600.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpm2600Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2600Duration()).orElse(0) + duration);
        } else if (RotationRange.RPM_RANGE_OVER_2600.getRange().contains(rotation)) {
            vehicleBaseStatisticsDay.setRpmOver2600Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getRpmOver2600Duration()).orElse(0) + duration);
        }
        if (vehicleBaseStatisticsDay.getMaxRpm() == null
                || rotation > vehicleBaseStatisticsDay.getMaxRpm()) {
            vehicleBaseStatisticsDay.setMaxRpm(rotation);
        }
        if (vehicleBaseStatisticsDay.getMinRpm() == null
                || rotation < vehicleBaseStatisticsDay.getMinRpm()) {
            vehicleBaseStatisticsDay.setMinRpm(rotation);
        }
        boolean idle = isIdle(workSpeedThreshold, vehicleStartRotation, speed, rotation);
        if (!idle) {
            vehicleBaseStatisticsDay.setNoIdleRpmSum(vehicleBaseStatisticsDay.getNoIdleRpmSum() + rotation);
            vehicleBaseStatisticsDay.setNoIdleRpmCount(vehicleBaseStatisticsDay.getNoIdleRpmCount() + 1);
            int noIdleAvgRpm = BigDecimal.valueOf(vehicleBaseStatisticsDay.getNoIdleRpmSum()).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getNoIdleRpmCount()), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setNoIdleAvgRpm(noIdleAvgRpm);
        }
        vehicleBaseStatisticsDay.setRpmSum(vehicleBaseStatisticsDay.getRpmSum() + rotation);
        vehicleBaseStatisticsDay.setRpmCount(vehicleBaseStatisticsDay.getRpmCount() + 1);
        int avgRpm = BigDecimal.valueOf(vehicleBaseStatisticsDay.getRpmSum()).
                divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getRpmCount()), 0,
                        BigDecimal.ROUND_HALF_UP).intValue();
        vehicleBaseStatisticsDay.setAvgRpm(avgRpm);
    }

    /**
     * 计算进气温度时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     */
    public void calIntakeAirTempRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                      LocationDataPoint locationDataPoint,
                                      int duration,
                                      int workSpeedThreshold, int vehicleStartRotation) {
        int intakeAirTem = locationDataPoint.getIntakeAirTem();
        if (!IntakeAirTempRange.INTAKE_AIR_TEMP_VALID.getRange().contains(intakeAirTem)) {
            return;
        }
        if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_50.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat50Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat50Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_70.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat70Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat70Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_80.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat80Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat80Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_85.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat85Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat85Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_90.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat90Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat90Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_95.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat95Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat95Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_100.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat100Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat100Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_105.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat105Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat105Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_110.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat110Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat110Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_115.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat115Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat115Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_120.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat120Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat120Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_125.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat125Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat125Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_130.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat130Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat130Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_135.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat135Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat135Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_140.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat140Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat140Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_145.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat145Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat145Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_150.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIat150Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIat150Duration()).orElse(0) + duration);
        } else if (IntakeAirTempRange.INTAKE_AIR_TEMP_RANGE_OVER_150.getRange().contains(intakeAirTem)) {
            vehicleBaseStatisticsDay.setIatOver150Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIatOver150Duration()).orElse(0) + duration);
        }

        if (vehicleBaseStatisticsDay.getMaxIat() == null
                || intakeAirTem > vehicleBaseStatisticsDay.getMaxIat()) {
            vehicleBaseStatisticsDay.setMaxIat(intakeAirTem);
        }
        if (vehicleBaseStatisticsDay.getMinIat() == null
                || intakeAirTem < vehicleBaseStatisticsDay.getMinIat()) {
            vehicleBaseStatisticsDay.setMinIat(intakeAirTem);
        }
        vehicleBaseStatisticsDay.setIatSum(vehicleBaseStatisticsDay.getIatSum() + intakeAirTem);
        vehicleBaseStatisticsDay.setIatCount(vehicleBaseStatisticsDay.getIatCount() + 1);
        int avgIat = BigDecimal.valueOf(vehicleBaseStatisticsDay.getIatSum()).
                divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getIatCount()), 0,
                        BigDecimal.ROUND_HALF_UP).intValue();
        vehicleBaseStatisticsDay.setAvgIat(avgIat);
    }

    /**
     * 计算进气压力时长
     *
     * @param vehicleBaseStatisticsDay
     * @param locationDataPoint
     * @param duration
     */
    public void calIntakeAirPressureRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                                          LocationDataPoint locationDataPoint,
                                          int duration,
                                          int workSpeedThreshold, int vehicleStartRotation) {
        int intakeAirPressure = locationDataPoint.getDpfPressure();
        if (!IntakeAirPressureRange.INTAKE_AIR_PRESSURE_VALID.getRange().contains(intakeAirPressure)) {
            return;
        }
        if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_50.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp50Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp50Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_60.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp60Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp60Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_70.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp70Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp70Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_80.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp80Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp80Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_90.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp90Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp90Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_100.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp100Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp100Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_110.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp110Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp110Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_120.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp120Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp120Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_130.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp130Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp130Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_140.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp140Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp140Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_150.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIp150Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIp150Duration()).orElse(0) + duration);
        } else if (IntakeAirPressureRange.INTAKE_AIR_PRESSURE_RANGE_OVER_150.getRange().contains(intakeAirPressure)) {
            vehicleBaseStatisticsDay.setIpOver150Duration(
                    Optional.ofNullable(vehicleBaseStatisticsDay.getIpOver150Duration()).orElse(0) + duration);
        }

        if (vehicleBaseStatisticsDay.getMaxIp() == null
                || intakeAirPressure > vehicleBaseStatisticsDay.getMaxIp()) {
            vehicleBaseStatisticsDay.setMaxIp(intakeAirPressure);
        }
        if (vehicleBaseStatisticsDay.getMinIp() == null
                || intakeAirPressure < vehicleBaseStatisticsDay.getMinIp()) {
            vehicleBaseStatisticsDay.setMinIp(intakeAirPressure);
        }
        vehicleBaseStatisticsDay.setIpSum(vehicleBaseStatisticsDay.getIpSum() + intakeAirPressure);
        vehicleBaseStatisticsDay.setIpCount(vehicleBaseStatisticsDay.getIpCount() + 1);
        int avgIp = BigDecimal.valueOf(vehicleBaseStatisticsDay.getIpSum()).
                divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getIpCount()), 0,
                        BigDecimal.ROUND_HALF_UP).intValue();
        vehicleBaseStatisticsDay.setAvgIp(avgIp);
    }

    /**
     * 计算里程油耗
     *
     * @param vehicleBaseStatisticsDay
     * @param points
     */
    public void calMileageAndFuel(VehicleBaseStatisticsDay vehicleBaseStatisticsDay, List<Point> points) {
        MileageAndFuel mileageAndFuel = Calculation.getStdMilAndFuel(points);
        vehicleBaseStatisticsDay.setMileage((int) (mileageAndFuel.getStdMileage() * 1000));
        vehicleBaseStatisticsDay.setFuelConsumption((int) (mileageAndFuel.getStdFuelCon() * 1000));
        //平均油耗 单位:L/100KM
        if (vehicleBaseStatisticsDay.getMileage() > 0) {
            double averageFuelConsumption = BigDecimal.valueOf(
                    vehicleBaseStatisticsDay.getFuelConsumption() * 100).
                    divide(BigDecimal.valueOf(vehicleBaseStatisticsDay.getMileage()), 2,
                            BigDecimal.ROUND_HALF_UP).doubleValue();
            vehicleBaseStatisticsDay.setAvgFuelConsumption(averageFuelConsumption);
        }
    }

    /**
     * 计算平均速度
     *
     * @param vehicleBaseStatisticsDay
     * @param usefulPercent
     * @param usefulSpeed
     */
    public void calAvgSpeed(VehicleBaseStatisticsDay vehicleBaseStatisticsDay,
                            double usefulPercent,
                            UsefulSpeed usefulSpeed) {
        //平均速度 单位：KM/H
        int workDuration = vehicleBaseStatisticsDay.getWorkDuration();
        if (workDuration > 0) {
            int avgSpeed = BigDecimal.valueOf(
                    vehicleBaseStatisticsDay.getMileage() * 3.6d).
                    divide(BigDecimal.valueOf(workDuration), 0,
                            BigDecimal.ROUND_HALF_UP).intValue();
            vehicleBaseStatisticsDay.setAvgSpeed(avgSpeed);
            List<Integer> usefulSpeedList = new ArrayList<>();
            if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed10Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed10MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed10MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed10MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed10MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed20Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed20MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed20MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed20MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed20MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed30Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed30MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed30MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed30MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed30MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed40Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed40MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed40MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed40MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed40MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed50Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed50MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed50MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed50MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed50MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed60Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed60MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed60MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed60MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed60MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed70Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed70MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed70MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed70MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed70MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed80Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed80MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed80MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed80MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed80MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed90Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed90MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed90MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed90MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed90MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed100Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed100MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed100MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed100MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed100MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed110Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed110MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed110MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed110MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed110MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed120Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeed120MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed120MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeed120MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeed120MaxUsefulSpeed());
                }
            } if ((Optional.ofNullable(vehicleBaseStatisticsDay.getSpeedOver120Duration())
                    .orElse(0) / (double) workDuration) > usefulPercent) {
                if (usefulSpeed.getSpeedOver120MinUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeedOver120MinUsefulSpeed());
                }
                if (usefulSpeed.getSpeedOver120MaxUsefulSpeed() != null) {
                    usefulSpeedList.add(usefulSpeed.getSpeedOver120MaxUsefulSpeed());
                }
            }
            if (usefulSpeedList.size() > 0) {
                IntSummaryStatistics intSummaryStatistics = usefulSpeedList.stream()
                        .mapToInt(Integer::intValue)
                        .summaryStatistics();
                vehicleBaseStatisticsDay.setMinUsefulSpeed(intSummaryStatistics.getMin());
                vehicleBaseStatisticsDay.setMaxUsefulSpeed(intSummaryStatistics.getMax());
            }
        }
    }

    /**
     * 修正速度时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctSpeedRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration() + vehicleBaseStatisticsDay.getIdleDuration();
        List<Integer> speed = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed10Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed20Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed30Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed40Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed60Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed110Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeed120Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getSpeedOver120Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, speed);
        vehicleBaseStatisticsDay.setSpeed10Duration(ints[0]);
        vehicleBaseStatisticsDay.setSpeed20Duration(ints[1]);
        vehicleBaseStatisticsDay.setSpeed30Duration(ints[2]);
        vehicleBaseStatisticsDay.setSpeed40Duration(ints[3]);
        vehicleBaseStatisticsDay.setSpeed50Duration(ints[4]);
        vehicleBaseStatisticsDay.setSpeed60Duration(ints[5]);
        vehicleBaseStatisticsDay.setSpeed70Duration(ints[6]);
        vehicleBaseStatisticsDay.setSpeed80Duration(ints[7]);
        vehicleBaseStatisticsDay.setSpeed90Duration(ints[8]);
        vehicleBaseStatisticsDay.setSpeed100Duration(ints[9]);
        vehicleBaseStatisticsDay.setSpeed110Duration(ints[10]);
        vehicleBaseStatisticsDay.setSpeed120Duration(ints[11]);
        vehicleBaseStatisticsDay.setSpeedOver120Duration(ints[12]);
    }

    /**
     * 修正水温时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctWaterTempRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp85Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp95Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp105Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp110Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp115Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp120Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp125Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp130Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp135Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp140Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp145Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTemp150Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getWorkWaterTempOver150Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setWorkWaterTemp50Duration(ints[0]);
        vehicleBaseStatisticsDay.setWorkWaterTemp70Duration(ints[1]);
        vehicleBaseStatisticsDay.setWorkWaterTemp80Duration(ints[2]);
        vehicleBaseStatisticsDay.setWorkWaterTemp85Duration(ints[3]);
        vehicleBaseStatisticsDay.setWorkWaterTemp90Duration(ints[4]);
        vehicleBaseStatisticsDay.setWorkWaterTemp95Duration(ints[5]);
        vehicleBaseStatisticsDay.setWorkWaterTemp100Duration(ints[6]);
        vehicleBaseStatisticsDay.setWorkWaterTemp105Duration(ints[7]);
        vehicleBaseStatisticsDay.setWorkWaterTemp110Duration(ints[8]);
        vehicleBaseStatisticsDay.setWorkWaterTemp115Duration(ints[9]);
        vehicleBaseStatisticsDay.setWorkWaterTemp120Duration(ints[10]);
        vehicleBaseStatisticsDay.setWorkWaterTemp125Duration(ints[11]);
        vehicleBaseStatisticsDay.setWorkWaterTemp130Duration(ints[12]);
        vehicleBaseStatisticsDay.setWorkWaterTemp135Duration(ints[13]);
        vehicleBaseStatisticsDay.setWorkWaterTemp140Duration(ints[14]);
        vehicleBaseStatisticsDay.setWorkWaterTemp145Duration(ints[15]);
        vehicleBaseStatisticsDay.setWorkWaterTemp150Duration(ints[16]);
        vehicleBaseStatisticsDay.setWorkWaterTempOver150Duration(ints[17]);

        totalDuration = vehicleBaseStatisticsDay.getIdleDuration();
        list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp85Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp95Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp105Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp110Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp115Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp120Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp125Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp130Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp135Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp140Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp145Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTemp150Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIdleWaterTempOver150Duration()).orElse(0));
        ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setIdleWaterTemp50Duration(ints[0]);
        vehicleBaseStatisticsDay.setIdleWaterTemp70Duration(ints[1]);
        vehicleBaseStatisticsDay.setIdleWaterTemp80Duration(ints[2]);
        vehicleBaseStatisticsDay.setIdleWaterTemp85Duration(ints[3]);
        vehicleBaseStatisticsDay.setIdleWaterTemp90Duration(ints[4]);
        vehicleBaseStatisticsDay.setIdleWaterTemp95Duration(ints[5]);
        vehicleBaseStatisticsDay.setIdleWaterTemp100Duration(ints[6]);
        vehicleBaseStatisticsDay.setIdleWaterTemp105Duration(ints[7]);
        vehicleBaseStatisticsDay.setIdleWaterTemp110Duration(ints[8]);
        vehicleBaseStatisticsDay.setIdleWaterTemp115Duration(ints[9]);
        vehicleBaseStatisticsDay.setIdleWaterTemp120Duration(ints[10]);
        vehicleBaseStatisticsDay.setIdleWaterTemp125Duration(ints[11]);
        vehicleBaseStatisticsDay.setIdleWaterTemp130Duration(ints[12]);
        vehicleBaseStatisticsDay.setIdleWaterTemp135Duration(ints[13]);
        vehicleBaseStatisticsDay.setIdleWaterTemp140Duration(ints[14]);
        vehicleBaseStatisticsDay.setIdleWaterTemp145Duration(ints[15]);
        vehicleBaseStatisticsDay.setIdleWaterTemp150Duration(ints[16]);
        vehicleBaseStatisticsDay.setIdleWaterTempOver150Duration(ints[17]);
    }

    /**
     * 修正油门开度时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctGasOpenPercentRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent0Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent10Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent20Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent30Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent40Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent60Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent99Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getGasOpenPercent100Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setGasOpenPercent0Duration(ints[0]);
        vehicleBaseStatisticsDay.setGasOpenPercent10Duration(ints[1]);
        vehicleBaseStatisticsDay.setGasOpenPercent20Duration(ints[2]);
        vehicleBaseStatisticsDay.setGasOpenPercent30Duration(ints[3]);
        vehicleBaseStatisticsDay.setGasOpenPercent40Duration(ints[4]);
        vehicleBaseStatisticsDay.setGasOpenPercent50Duration(ints[5]);
        vehicleBaseStatisticsDay.setGasOpenPercent60Duration(ints[6]);
        vehicleBaseStatisticsDay.setGasOpenPercent70Duration(ints[7]);
        vehicleBaseStatisticsDay.setGasOpenPercent80Duration(ints[8]);
        vehicleBaseStatisticsDay.setGasOpenPercent90Duration(ints[9]);
        vehicleBaseStatisticsDay.setGasOpenPercent99Duration(ints[10]);
        vehicleBaseStatisticsDay.setGasOpenPercent100Duration(ints[11]);
    }

    /**
     * 修正扭矩时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctTorqueRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque0Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque10Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque20Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque30Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque40Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque60Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque99Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getTorque100Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setTorque0Duration(ints[0]);
        vehicleBaseStatisticsDay.setTorque10Duration(ints[1]);
        vehicleBaseStatisticsDay.setTorque20Duration(ints[2]);
        vehicleBaseStatisticsDay.setTorque30Duration(ints[3]);
        vehicleBaseStatisticsDay.setTorque40Duration(ints[4]);
        vehicleBaseStatisticsDay.setTorque50Duration(ints[5]);
        vehicleBaseStatisticsDay.setTorque60Duration(ints[6]);
        vehicleBaseStatisticsDay.setTorque70Duration(ints[7]);
        vehicleBaseStatisticsDay.setTorque80Duration(ints[8]);
        vehicleBaseStatisticsDay.setTorque90Duration(ints[9]);
        vehicleBaseStatisticsDay.setTorque99Duration(ints[10]);
        vehicleBaseStatisticsDay.setTorque100Duration(ints[11]);
    }

    /**
     * 修正区间时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctRotationRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration() + vehicleBaseStatisticsDay.getIdleDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm650Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm800Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1400Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm1700Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2000Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2300Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpm2600Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getRpmOver2600Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setRpm650Duration(ints[0]);
        vehicleBaseStatisticsDay.setRpm800Duration(ints[1]);
        vehicleBaseStatisticsDay.setRpm1100Duration(ints[2]);
        vehicleBaseStatisticsDay.setRpm1400Duration(ints[3]);
        vehicleBaseStatisticsDay.setRpm1700Duration(ints[4]);
        vehicleBaseStatisticsDay.setRpm2000Duration(ints[5]);
        vehicleBaseStatisticsDay.setRpm2300Duration(ints[6]);
        vehicleBaseStatisticsDay.setRpm2600Duration(ints[7]);
        vehicleBaseStatisticsDay.setRpmOver2600Duration(ints[8]);

        vehicleBaseStatisticsDay.setEcoRpmDuration(vehicleBaseStatisticsDay.getRpm1400Duration());
        if (totalDuration > 0) {
            int ecoRpmPercent = BigDecimal.valueOf(vehicleBaseStatisticsDay.getEcoRpmDuration() * 100)
                    .divide(BigDecimal.valueOf(totalDuration), 0, BigDecimal.ROUND_HALF_DOWN).intValue();
            vehicleBaseStatisticsDay.setEcoRpmPercent(ecoRpmPercent);
        } else {
            vehicleBaseStatisticsDay.setEcoRpmPercent(0);
        }
    }

    /**
     * 修正进气温度时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctIntakeAirTempRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration() + vehicleBaseStatisticsDay.getIdleDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat85Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat95Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat105Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat110Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat115Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat120Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat125Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat130Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat135Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat140Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat145Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIat150Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIatOver150Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setIat50Duration(ints[0]);
        vehicleBaseStatisticsDay.setIat70Duration(ints[1]);
        vehicleBaseStatisticsDay.setIat80Duration(ints[2]);
        vehicleBaseStatisticsDay.setIat85Duration(ints[3]);
        vehicleBaseStatisticsDay.setIat90Duration(ints[4]);
        vehicleBaseStatisticsDay.setIat95Duration(ints[5]);
        vehicleBaseStatisticsDay.setIat100Duration(ints[6]);
        vehicleBaseStatisticsDay.setIat105Duration(ints[7]);
        vehicleBaseStatisticsDay.setIat110Duration(ints[8]);
        vehicleBaseStatisticsDay.setIat115Duration(ints[9]);
        vehicleBaseStatisticsDay.setIat120Duration(ints[10]);
        vehicleBaseStatisticsDay.setIat125Duration(ints[11]);
        vehicleBaseStatisticsDay.setIat130Duration(ints[12]);
        vehicleBaseStatisticsDay.setIat135Duration(ints[13]);
        vehicleBaseStatisticsDay.setIat140Duration(ints[14]);
        vehicleBaseStatisticsDay.setIat145Duration(ints[15]);
        vehicleBaseStatisticsDay.setIat150Duration(ints[16]);
        vehicleBaseStatisticsDay.setIatOver150Duration(ints[17]);
    }

    /**
     * 修正进气压力时长
     *
     * @param vehicleBaseStatisticsDay
     */
    public void correctIntakeAirPressureRange(VehicleBaseStatisticsDay vehicleBaseStatisticsDay) {
        int totalDuration = vehicleBaseStatisticsDay.getWorkDuration() + vehicleBaseStatisticsDay.getIdleDuration();
        List<Integer> list = Arrays.asList(
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp50Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp60Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp70Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp80Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp90Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp100Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp110Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp120Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp130Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp140Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIp150Duration()).orElse(0),
                Optional.ofNullable(vehicleBaseStatisticsDay.getIpOver150Duration()).orElse(0));
        int[] ints = getCorrectResult(totalDuration, list);
        vehicleBaseStatisticsDay.setIp50Duration(ints[0]);
        vehicleBaseStatisticsDay.setIp60Duration(ints[1]);
        vehicleBaseStatisticsDay.setIp70Duration(ints[2]);
        vehicleBaseStatisticsDay.setIp80Duration(ints[3]);
        vehicleBaseStatisticsDay.setIp90Duration(ints[4]);
        vehicleBaseStatisticsDay.setIp100Duration(ints[5]);
        vehicleBaseStatisticsDay.setIp110Duration(ints[6]);
        vehicleBaseStatisticsDay.setIp120Duration(ints[7]);
        vehicleBaseStatisticsDay.setIp130Duration(ints[8]);
        vehicleBaseStatisticsDay.setIp140Duration(ints[9]);
        vehicleBaseStatisticsDay.setIp150Duration(ints[10]);
        vehicleBaseStatisticsDay.setIpOver150Duration(ints[11]);
    }

    private int[] getCorrectResult(int totalDuration, List<Integer> list) {
        int[] ints = new int[list.size()];
        int beforeCorrectSum = list.stream().mapToInt(Integer::intValue).sum();
        if (beforeCorrectSum > 0) {
            ints = list.stream().mapToInt(o -> BigDecimal.valueOf(o)
                    .divide(BigDecimal.valueOf(beforeCorrectSum), 6, BigDecimal.ROUND_DOWN)
                    .multiply(BigDecimal.valueOf(totalDuration))
                    .setScale(0, BigDecimal.ROUND_DOWN).intValue()).toArray();
            int afterCorrect = Arrays.stream(ints).sum();
            ints[0] = ints[0] + (totalDuration - afterCorrect);
        }
        return ints;
    }


}
